home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / sparc / include / asm / floppy_64.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  18.9 KB  |  779 lines

  1. /* floppy.h: Sparc specific parts of the Floppy driver.
  2.  *
  3.  * Copyright (C) 1996, 2007, 2008 David S. Miller (davem@davemloft.net)
  4.  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  5.  *
  6.  * Ultra/PCI support added: Sep 1997  Eddie C. Dost  (ecd@skynet.be)
  7.  */
  8.  
  9. #ifndef __ASM_SPARC64_FLOPPY_H
  10. #define __ASM_SPARC64_FLOPPY_H
  11.  
  12. #include <linux/of.h>
  13. #include <linux/of_device.h>
  14. #include <linux/dma-mapping.h>
  15.  
  16. #include <asm/auxio.h>
  17.  
  18. /*
  19.  * Define this to enable exchanging drive 0 and 1 if only drive 1 is
  20.  * probed on PCI machines.
  21.  */
  22. #undef PCI_FDC_SWAP_DRIVES
  23.  
  24.  
  25. /* References:
  26.  * 1) Netbsd Sun floppy driver.
  27.  * 2) NCR 82077 controller manual
  28.  * 3) Intel 82077 controller manual
  29.  */
  30. struct sun_flpy_controller {
  31.     volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
  32.     volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
  33.     volatile unsigned char dor_82077;     /* Digital Output reg. */
  34.     volatile unsigned char tapectl_82077; /* Tape Control reg */
  35.     volatile unsigned char status_82077;  /* Main Status Register. */
  36. #define drs_82077              status_82077   /* Digital Rate Select reg. */
  37.     volatile unsigned char data_82077;    /* Data fifo. */
  38.     volatile unsigned char ___unused;
  39.     volatile unsigned char dir_82077;     /* Digital Input reg. */
  40. #define dcr_82077              dir_82077      /* Config Control reg. */
  41. };
  42.  
  43. /* You'll only ever find one controller on an Ultra anyways. */
  44. static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
  45. unsigned long fdc_status;
  46. static struct of_device *floppy_op = NULL;
  47.  
  48. struct sun_floppy_ops {
  49.     unsigned char    (*fd_inb) (unsigned long port);
  50.     void        (*fd_outb) (unsigned char value, unsigned long port);
  51.     void        (*fd_enable_dma) (void);
  52.     void        (*fd_disable_dma) (void);
  53.     void        (*fd_set_dma_mode) (int);
  54.     void        (*fd_set_dma_addr) (char *);
  55.     void        (*fd_set_dma_count) (int);
  56.     unsigned int    (*get_dma_residue) (void);
  57.     int        (*fd_request_irq) (void);
  58.     void        (*fd_free_irq) (void);
  59.     int        (*fd_eject) (int);
  60. };
  61.  
  62. static struct sun_floppy_ops sun_fdops;
  63.  
  64. #define fd_inb(port)              sun_fdops.fd_inb(port)
  65. #define fd_outb(value,port)       sun_fdops.fd_outb(value,port)
  66. #define fd_enable_dma()           sun_fdops.fd_enable_dma()
  67. #define fd_disable_dma()          sun_fdops.fd_disable_dma()
  68. #define fd_request_dma()          (0) /* nothing... */
  69. #define fd_free_dma()             /* nothing... */
  70. #define fd_clear_dma_ff()         /* nothing... */
  71. #define fd_set_dma_mode(mode)     sun_fdops.fd_set_dma_mode(mode)
  72. #define fd_set_dma_addr(addr)     sun_fdops.fd_set_dma_addr(addr)
  73. #define fd_set_dma_count(count)   sun_fdops.fd_set_dma_count(count)
  74. #define get_dma_residue(x)        sun_fdops.get_dma_residue()
  75. #define fd_cacheflush(addr, size) /* nothing... */
  76. #define fd_request_irq()          sun_fdops.fd_request_irq()
  77. #define fd_free_irq()             sun_fdops.fd_free_irq()
  78. #define fd_eject(drive)           sun_fdops.fd_eject(drive)
  79.  
  80. /* Super paranoid... */
  81. #undef HAVE_DISABLE_HLT
  82.  
  83. static int sun_floppy_types[2] = { 0, 0 };
  84.  
  85. /* Here is where we catch the floppy driver trying to initialize,
  86.  * therefore this is where we call the PROM device tree probing
  87.  * routine etc. on the Sparc.
  88.  */
  89. #define FLOPPY0_TYPE        sun_floppy_init()
  90. #define FLOPPY1_TYPE        sun_floppy_types[1]
  91.  
  92. #define FDC1            ((unsigned long)sun_fdc)
  93.  
  94. #define N_FDC    1
  95. #define N_DRIVE  8
  96.  
  97. /* No 64k boundary crossing problems on the Sparc. */
  98. #define CROSS_64KB(a,s) (0)
  99.  
  100. static unsigned char sun_82077_fd_inb(unsigned long port)
  101. {
  102.     udelay(5);
  103.     switch(port & 7) {
  104.     default:
  105.         printk("floppy: Asked to read unknown port %lx\n", port);
  106.         panic("floppy: Port bolixed.");
  107.     case 4: /* FD_STATUS */
  108.         return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
  109.     case 5: /* FD_DATA */
  110.         return sbus_readb(&sun_fdc->data_82077);
  111.     case 7: /* FD_DIR */
  112.         /* XXX: Is DCL on 0x80 in sun4m? */
  113.         return sbus_readb(&sun_fdc->dir_82077);
  114.     };
  115.     panic("sun_82072_fd_inb: How did I get here?");
  116. }
  117.  
  118. static void sun_82077_fd_outb(unsigned char value, unsigned long port)
  119. {
  120.     udelay(5);
  121.     switch(port & 7) {
  122.     default:
  123.         printk("floppy: Asked to write to unknown port %lx\n", port);
  124.         panic("floppy: Port bolixed.");
  125.     case 2: /* FD_DOR */
  126.         /* Happily, the 82077 has a real DOR register. */
  127.         sbus_writeb(value, &sun_fdc->dor_82077);
  128.         break;
  129.     case 5: /* FD_DATA */
  130.         sbus_writeb(value, &sun_fdc->data_82077);
  131.         break;
  132.     case 7: /* FD_DCR */
  133.         sbus_writeb(value, &sun_fdc->dcr_82077);
  134.         break;
  135.     case 4: /* FD_STATUS */
  136.         sbus_writeb(value, &sun_fdc->status_82077);
  137.         break;
  138.     };
  139.     return;
  140. }
  141.  
  142. /* For pseudo-dma (Sun floppy drives have no real DMA available to
  143.  * them so we must eat the data fifo bytes directly ourselves) we have
  144.  * three state variables.  doing_pdma tells our inline low-level
  145.  * assembly floppy interrupt entry point whether it should sit and eat
  146.  * bytes from the fifo or just transfer control up to the higher level
  147.  * floppy interrupt c-code.  I tried very hard but I could not get the
  148.  * pseudo-dma to work in c-code without getting many overruns and
  149.  * underruns.  If non-zero, doing_pdma encodes the direction of
  150.  * the transfer for debugging.  1=read 2=write
  151.  */
  152. unsigned char *pdma_vaddr;
  153. unsigned long pdma_size;
  154. volatile int doing_pdma = 0;
  155.  
  156. /* This is software state */
  157. char *pdma_base = NULL;
  158. unsigned long pdma_areasize;
  159.  
  160. /* Common routines to all controller types on the Sparc. */
  161. static void sun_fd_disable_dma(void)
  162. {
  163.     doing_pdma = 0;
  164.     if (pdma_base) {
  165.         mmu_unlockarea(pdma_base, pdma_areasize);
  166.         pdma_base = NULL;
  167.     }
  168. }
  169.  
  170. static void sun_fd_set_dma_mode(int mode)
  171. {
  172.     switch(mode) {
  173.     case DMA_MODE_READ:
  174.         doing_pdma = 1;
  175.         break;
  176.     case DMA_MODE_WRITE:
  177.         doing_pdma = 2;
  178.         break;
  179.     default:
  180.         printk("Unknown dma mode %d\n", mode);
  181.         panic("floppy: Giving up...");
  182.     }
  183. }
  184.  
  185. static void sun_fd_set_dma_addr(char *buffer)
  186. {
  187.     pdma_vaddr = buffer;
  188. }
  189.  
  190. static void sun_fd_set_dma_count(int length)
  191. {
  192.     pdma_size = length;
  193. }
  194.  
  195. static void sun_fd_enable_dma(void)
  196. {
  197.     pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
  198.     pdma_base = pdma_vaddr;
  199.     pdma_areasize = pdma_size;
  200. }
  201.  
  202. irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
  203. {
  204.     if (likely(doing_pdma)) {
  205.         void __iomem *stat = (void __iomem *) fdc_status;
  206.         unsigned char *vaddr = pdma_vaddr;
  207.         unsigned long size = pdma_size;
  208.         u8 val;
  209.  
  210.         while (size) {
  211.             val = readb(stat);
  212.             if (unlikely(!(val & 0x80))) {
  213.                 pdma_vaddr = vaddr;
  214.                 pdma_size = size;
  215.                 return IRQ_HANDLED;
  216.             }
  217.             if (unlikely(!(val & 0x20))) {
  218.                 pdma_vaddr = vaddr;
  219.                 pdma_size = size;
  220.                 doing_pdma = 0;
  221.                 goto main_interrupt;
  222.             }
  223.             if (val & 0x40) {
  224.                 /* read */
  225.                 *vaddr++ = readb(stat + 1);
  226.             } else {
  227.                 unsigned char data = *vaddr++;
  228.  
  229.                 /* write */
  230.                 writeb(data, stat + 1);
  231.             }
  232.             size--;
  233.         }
  234.  
  235.         pdma_vaddr = vaddr;
  236.         pdma_size = size;
  237.  
  238.         /* Send Terminal Count pulse to floppy controller. */
  239.         val = readb(auxio_register);
  240.         val |= AUXIO_AUX1_FTCNT;
  241.         writeb(val, auxio_register);
  242.         val &= ~AUXIO_AUX1_FTCNT;
  243.         writeb(val, auxio_register);
  244.  
  245.         doing_pdma = 0;
  246.     }
  247.  
  248. main_interrupt:
  249.     return floppy_interrupt(irq, dev_cookie);
  250. }
  251.  
  252. static int sun_fd_request_irq(void)
  253. {
  254.     static int once = 0;
  255.     int error;
  256.  
  257.     if(!once) {
  258.         once = 1;
  259.  
  260.         error = request_irq(FLOPPY_IRQ, sparc_floppy_irq,
  261.                     IRQF_DISABLED, "floppy", NULL);
  262.  
  263.         return ((error == 0) ? 0 : -1);
  264.     }
  265.     return 0;
  266. }
  267.  
  268. static void sun_fd_free_irq(void)
  269. {
  270. }
  271.  
  272. static unsigned int sun_get_dma_residue(void)
  273. {
  274.     /* XXX This isn't really correct. XXX */
  275.     return 0;
  276. }
  277.  
  278. static int sun_fd_eject(int drive)
  279. {
  280.     set_dor(0x00, 0xff, 0x90);
  281.     udelay(500);
  282.     set_dor(0x00, 0x6f, 0x00);
  283.     udelay(500);
  284.     return 0;
  285. }
  286.  
  287. #include <asm/ebus_dma.h>
  288. #include <asm/ns87303.h>
  289.  
  290. static struct ebus_dma_info sun_pci_fd_ebus_dma;
  291. static struct device *sun_floppy_dev;
  292. static int sun_pci_broken_drive = -1;
  293.  
  294. struct sun_pci_dma_op {
  295.     unsigned int     addr;
  296.     int        len;
  297.     int        direction;
  298.     char        *buf;
  299. };
  300. static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
  301. static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
  302.  
  303. extern irqreturn_t floppy_interrupt(int irq, void *dev_id);
  304.  
  305. static unsigned char sun_pci_fd_inb(unsigned long port)
  306. {
  307.     udelay(5);
  308.     return inb(port);
  309. }
  310.  
  311. static void sun_pci_fd_outb(unsigned char val, unsigned long port)
  312. {
  313.     udelay(5);
  314.     outb(val, port);
  315. }
  316.  
  317. static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port)
  318. {
  319.     udelay(5);
  320.     /*
  321.      * XXX: Due to SUN's broken floppy connector on AX and AXi
  322.      *      we need to turn on MOTOR_0 also, if the floppy is
  323.      *      jumpered to DS1 (like most PC floppies are). I hope
  324.      *      this does not hurt correct hardware like the AXmp.
  325.      *      (Eddie, Sep 12 1998).
  326.      */
  327.     if (port == ((unsigned long)sun_fdc) + 2) {
  328.         if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
  329.             val |= 0x10;
  330.         }
  331.     }
  332.     outb(val, port);
  333. }
  334.  
  335. #ifdef PCI_FDC_SWAP_DRIVES
  336. static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port)
  337. {
  338.     udelay(5);
  339.     /*
  340.      * XXX: Due to SUN's broken floppy connector on AX and AXi
  341.      *      we need to turn on MOTOR_0 also, if the floppy is
  342.      *      jumpered to DS1 (like most PC floppies are). I hope
  343.      *      this does not hurt correct hardware like the AXmp.
  344.      *      (Eddie, Sep 12 1998).
  345.      */
  346.     if (port == ((unsigned long)sun_fdc) + 2) {
  347.         if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
  348.             val &= ~(0x03);
  349.             val |= 0x21;
  350.         }
  351.     }
  352.     outb(val, port);
  353. }
  354. #endif /* PCI_FDC_SWAP_DRIVES */
  355.  
  356. static void sun_pci_fd_enable_dma(void)
  357. {
  358.     BUG_ON((NULL == sun_pci_dma_pending.buf)     ||
  359.         (0      == sun_pci_dma_pending.len)     ||
  360.         (0      == sun_pci_dma_pending.direction));
  361.  
  362.     sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
  363.     sun_pci_dma_current.len = sun_pci_dma_pending.len;
  364.     sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
  365.  
  366.     sun_pci_dma_pending.buf  = NULL;
  367.     sun_pci_dma_pending.len  = 0;
  368.     sun_pci_dma_pending.direction = 0;
  369.     sun_pci_dma_pending.addr = -1U;
  370.  
  371.     sun_pci_dma_current.addr =
  372.         dma_map_single(sun_floppy_dev,
  373.                    sun_pci_dma_current.buf,
  374.                    sun_pci_dma_current.len,
  375.                    sun_pci_dma_current.direction);
  376.  
  377.     ebus_dma_enable(&sun_pci_fd_ebus_dma, 1);
  378.  
  379.     if (ebus_dma_request(&sun_pci_fd_ebus_dma,
  380.                  sun_pci_dma_current.addr,
  381.                  sun_pci_dma_current.len))
  382.         BUG();
  383. }
  384.  
  385. static void sun_pci_fd_disable_dma(void)
  386. {
  387.     ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
  388.     if (sun_pci_dma_current.addr != -1U)
  389.         dma_unmap_single(sun_floppy_dev,
  390.                  sun_pci_dma_current.addr,
  391.                  sun_pci_dma_current.len,
  392.                  sun_pci_dma_current.direction);
  393.     sun_pci_dma_current.addr = -1U;
  394. }
  395.  
  396. static void sun_pci_fd_set_dma_mode(int mode)
  397. {
  398.     if (mode == DMA_MODE_WRITE)
  399.         sun_pci_dma_pending.direction = DMA_TO_DEVICE;
  400.     else
  401.         sun_pci_dma_pending.direction = DMA_FROM_DEVICE;
  402.  
  403.     ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
  404. }
  405.  
  406. static void sun_pci_fd_set_dma_count(int length)
  407. {
  408.     sun_pci_dma_pending.len = length;
  409. }
  410.  
  411. static void sun_pci_fd_set_dma_addr(char *buffer)
  412. {
  413.     sun_pci_dma_pending.buf = buffer;
  414. }
  415.  
  416. static unsigned int sun_pci_get_dma_residue(void)
  417. {
  418.     return ebus_dma_residue(&sun_pci_fd_ebus_dma);
  419. }
  420.  
  421. static int sun_pci_fd_request_irq(void)
  422. {
  423.     return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
  424. }
  425.  
  426. static void sun_pci_fd_free_irq(void)
  427. {
  428.     ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
  429. }
  430.  
  431. static int sun_pci_fd_eject(int drive)
  432. {
  433.     return -EINVAL;
  434. }
  435.  
  436. void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
  437. {
  438.     floppy_interrupt(0, NULL);
  439. }
  440.  
  441. /*
  442.  * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
  443.  * even if this is configured using DS1, thus looks like /dev/fd1 with
  444.  * the cabling used in Ultras.
  445.  */
  446. #define DOR    (port + 2)
  447. #define MSR    (port + 4)
  448. #define FIFO    (port + 5)
  449.  
  450. static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
  451.                     unsigned long reg)
  452. {
  453.     unsigned char status;
  454.     int timeout = 1000;
  455.  
  456.     while (!((status = inb(MSR)) & 0x80) && --timeout)
  457.         udelay(100);
  458.     outb(val, reg);
  459. }
  460.  
  461. static unsigned char sun_pci_fd_sensei(unsigned long port)
  462. {
  463.     unsigned char result[2] = { 0x70, 0x00 };
  464.     unsigned char status;
  465.     int i = 0;
  466.  
  467.     sun_pci_fd_out_byte(port, 0x08, FIFO);
  468.     do {
  469.         int timeout = 1000;
  470.  
  471.         while (!((status = inb(MSR)) & 0x80) && --timeout)
  472.             udelay(100);
  473.  
  474.         if (!timeout)
  475.             break;
  476.  
  477.         if ((status & 0xf0) == 0xd0)
  478.             result[i++] = inb(FIFO);
  479.         else
  480.             break;
  481.     } while (i < 2);
  482.  
  483.     return result[0];
  484. }
  485.  
  486. static void sun_pci_fd_reset(unsigned long port)
  487. {
  488.     unsigned char mask = 0x00;
  489.     unsigned char status;
  490.     int timeout = 10000;
  491.  
  492.     outb(0x80, MSR);
  493.     do {
  494.         status = sun_pci_fd_sensei(port);
  495.         if ((status & 0xc0) == 0xc0)
  496.             mask |= 1 << (status & 0x03);
  497.         else
  498.             udelay(100);
  499.     } while ((mask != 0x0f) && --timeout);
  500. }
  501.  
  502. static int sun_pci_fd_test_drive(unsigned long port, int drive)
  503. {
  504.     unsigned char status, data;
  505.     int timeout = 1000;
  506.     int ready;
  507.  
  508.     sun_pci_fd_reset(port);
  509.  
  510.     data = (0x10 << drive) | 0x0c | drive;
  511.     sun_pci_fd_out_byte(port, data, DOR);
  512.  
  513.     sun_pci_fd_out_byte(port, 0x07, FIFO);
  514.     sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
  515.  
  516.     do {
  517.         udelay(100);
  518.         status = sun_pci_fd_sensei(port);
  519.     } while (((status & 0xc0) == 0x80) && --timeout);
  520.  
  521.     if (!timeout)
  522.         ready = 0;
  523.     else
  524.         ready = (status & 0x10) ? 0 : 1;
  525.  
  526.     sun_pci_fd_reset(port);
  527.     return ready;
  528. }
  529. #undef FIFO
  530. #undef MSR
  531. #undef DOR
  532.  
  533. static int __init ebus_fdthree_p(struct device_node *dp)
  534. {
  535.     if (!strcmp(dp->name, "fdthree"))
  536.         return 1;
  537.     if (!strcmp(dp->name, "floppy")) {
  538.         const char *compat;
  539.  
  540.         compat = of_get_property(dp, "compatible", NULL);
  541.         if (compat && !strcmp(compat, "fdthree"))
  542.             return 1;
  543.     }
  544.     return 0;
  545. }
  546.  
  547. static unsigned long __init sun_floppy_init(void)
  548. {
  549.     static int initialized = 0;
  550.     struct device_node *dp;
  551.     struct of_device *op;
  552.     const char *prop;
  553.     char state[128];
  554.  
  555.     if (initialized)
  556.         return sun_floppy_types[0];
  557.     initialized = 1;
  558.  
  559.     op = NULL;
  560.  
  561.     for_each_node_by_name(dp, "SUNW,fdtwo") {
  562.         if (strcmp(dp->parent->name, "sbus"))
  563.             continue;
  564.         op = of_find_device_by_node(dp);
  565.         if (op)
  566.             break;
  567.     }
  568.     if (op) {
  569.         floppy_op = op;
  570.         FLOPPY_IRQ = op->irqs[0];
  571.     } else {
  572.         struct device_node *ebus_dp;
  573.         void __iomem *auxio_reg;
  574.         const char *state_prop;
  575.         unsigned long config;
  576.  
  577.         dp = NULL;
  578.         for_each_node_by_name(ebus_dp, "ebus") {
  579.             for (dp = ebus_dp->child; dp; dp = dp->sibling) {
  580.                 if (ebus_fdthree_p(dp))
  581.                     goto found_fdthree;
  582.             }
  583.         }
  584.     found_fdthree:
  585.         if (!dp)
  586.             return 0;
  587.  
  588.         op = of_find_device_by_node(dp);
  589.         if (!op)
  590.             return 0;
  591.  
  592.         state_prop = of_get_property(op->node, "status", NULL);
  593.         if (state_prop && !strncmp(state_prop, "disabled", 8))
  594.             return 0;
  595.  
  596.         FLOPPY_IRQ = op->irqs[0];
  597.  
  598.         /* Make sure the high density bit is set, some systems
  599.          * (most notably Ultra5/Ultra10) come up with it clear.
  600.          */
  601.         auxio_reg = (void __iomem *) op->resource[2].start;
  602.         writel(readl(auxio_reg)|0x2, auxio_reg);
  603.  
  604.         sun_floppy_dev = &op->dev;
  605.  
  606.         spin_lock_init(&sun_pci_fd_ebus_dma.lock);
  607.  
  608.         /* XXX ioremap */
  609.         sun_pci_fd_ebus_dma.regs = (void __iomem *)
  610.             op->resource[1].start;
  611.         if (!sun_pci_fd_ebus_dma.regs)
  612.             return 0;
  613.  
  614.         sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
  615.                          EBUS_DMA_FLAG_TCI_DISABLE);
  616.         sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback;
  617.         sun_pci_fd_ebus_dma.client_cookie = NULL;
  618.         sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ;
  619.         strcpy(sun_pci_fd_ebus_dma.name, "floppy");
  620.         if (ebus_dma_register(&sun_pci_fd_ebus_dma))
  621.             return 0;
  622.  
  623.         /* XXX ioremap */
  624.         sun_fdc = (struct sun_flpy_controller *) op->resource[0].start;
  625.  
  626.         sun_fdops.fd_inb = sun_pci_fd_inb;
  627.         sun_fdops.fd_outb = sun_pci_fd_outb;
  628.  
  629.         can_use_virtual_dma = use_virtual_dma = 0;
  630.         sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
  631.         sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
  632.         sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
  633.         sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
  634.         sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
  635.         sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
  636.  
  637.         sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
  638.         sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
  639.  
  640.         sun_fdops.fd_eject = sun_pci_fd_eject;
  641.  
  642.         fdc_status = (unsigned long) &sun_fdc->status_82077;
  643.  
  644.         /*
  645.          * XXX: Find out on which machines this is really needed.
  646.          */
  647.         if (1) {
  648.             sun_pci_broken_drive = 1;
  649.             sun_fdops.fd_outb = sun_pci_fd_broken_outb;
  650.         }
  651.  
  652.         allowed_drive_mask = 0;
  653.         if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
  654.             sun_floppy_types[0] = 4;
  655.         if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
  656.             sun_floppy_types[1] = 4;
  657.  
  658.         /*
  659.          * Find NS87303 SuperIO config registers (through ecpp).
  660.          */
  661.         config = 0;
  662.         for (dp = ebus_dp->child; dp; dp = dp->sibling) {
  663.             if (!strcmp(dp->name, "ecpp")) {
  664.                 struct of_device *ecpp_op;
  665.  
  666.                 ecpp_op = of_find_device_by_node(dp);
  667.                 if (ecpp_op)
  668.                     config = ecpp_op->resource[1].start;
  669.                 goto config_done;
  670.             }
  671.         }
  672.     config_done:
  673.  
  674.         /*
  675.          * Sanity check, is this really the NS87303?
  676.          */
  677.         switch (config & 0x3ff) {
  678.         case 0x02e:
  679.         case 0x15c:
  680.         case 0x26e:
  681.         case 0x398:
  682.             break;
  683.         default:
  684.             config = 0;
  685.         }
  686.  
  687.         if (!config)
  688.             return sun_floppy_types[0];
  689.  
  690.         /* Enable PC-AT mode. */
  691.         ns87303_modify(config, ASC, 0, 0xc0);
  692.  
  693. #ifdef PCI_FDC_SWAP_DRIVES
  694.         /*
  695.          * If only Floppy 1 is present, swap drives.
  696.          */
  697.         if (!sun_floppy_types[0] && sun_floppy_types[1]) {
  698.             /*
  699.              * Set the drive exchange bit in FCR on NS87303,
  700.              * make sure other bits are sane before doing so.
  701.              */
  702.             ns87303_modify(config, FER, FER_EDM, 0);
  703.             ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
  704.             ns87303_modify(config, FCR, 0, FCR_LDE);
  705.  
  706.             config = sun_floppy_types[0];
  707.             sun_floppy_types[0] = sun_floppy_types[1];
  708.             sun_floppy_types[1] = config;
  709.  
  710.             if (sun_pci_broken_drive != -1) {
  711.                 sun_pci_broken_drive = 1 - sun_pci_broken_drive;
  712.                 sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
  713.             }
  714.         }
  715. #endif /* PCI_FDC_SWAP_DRIVES */
  716.  
  717.         return sun_floppy_types[0];
  718.     }
  719.     prop = of_get_property(op->node, "status", NULL);
  720.     if (prop && !strncmp(state, "disabled", 8))
  721.         return 0;
  722.  
  723.     /*
  724.      * We cannot do of_ioremap here: it does request_region,
  725.      * which the generic floppy driver tries to do once again.
  726.      * But we must use the sdev resource values as they have
  727.      * had parent ranges applied.
  728.      */
  729.     sun_fdc = (struct sun_flpy_controller *)
  730.         (op->resource[0].start +
  731.          ((op->resource[0].flags & 0x1ffUL) << 32UL));
  732.  
  733.     /* Last minute sanity check... */
  734.     if (sbus_readb(&sun_fdc->status1_82077) == 0xff) {
  735.         sun_fdc = (struct sun_flpy_controller *)-1;
  736.         return 0;
  737.     }
  738.  
  739.         sun_fdops.fd_inb = sun_82077_fd_inb;
  740.         sun_fdops.fd_outb = sun_82077_fd_outb;
  741.  
  742.     can_use_virtual_dma = use_virtual_dma = 1;
  743.     sun_fdops.fd_enable_dma = sun_fd_enable_dma;
  744.     sun_fdops.fd_disable_dma = sun_fd_disable_dma;
  745.     sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
  746.     sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
  747.     sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
  748.     sun_fdops.get_dma_residue = sun_get_dma_residue;
  749.  
  750.     sun_fdops.fd_request_irq = sun_fd_request_irq;
  751.     sun_fdops.fd_free_irq = sun_fd_free_irq;
  752.  
  753.     sun_fdops.fd_eject = sun_fd_eject;
  754.  
  755.         fdc_status = (unsigned long) &sun_fdc->status_82077;
  756.  
  757.     /* Success... */
  758.     allowed_drive_mask = 0x01;
  759.     sun_floppy_types[0] = 4;
  760.     sun_floppy_types[1] = 0;
  761.  
  762.     return sun_floppy_types[0];
  763. }
  764.  
  765. #define EXTRA_FLOPPY_PARAMS
  766.  
  767. static DEFINE_SPINLOCK(dma_spin_lock);
  768.  
  769. #define claim_dma_lock() \
  770. ({    unsigned long flags; \
  771.     spin_lock_irqsave(&dma_spin_lock, flags); \
  772.     flags; \
  773. })
  774.  
  775. #define release_dma_lock(__flags) \
  776.     spin_unlock_irqrestore(&dma_spin_lock, __flags);
  777.  
  778. #endif /* !(__ASM_SPARC64_FLOPPY_H) */
  779.